package com.project.common.data.mybatis.mapper;

import com.project.common.data.mybatis.action.CriteriaQuery;
import com.project.common.filter.AbstractFilter;
import com.project.common.pagination.PagedRecord;
import com.project.common.pagination.PaginationContext;

import java.io.Serializable;

public interface PaginationMapper<K extends Serializable, F extends AbstractFilter<K, F>> {
    Long count(F filter);

    default <M> PagedRecord<M> pagination(CriteriaQuery<K, M, F> query, F filter, int pageIndex, int pageSize) {
        Long total = this.count(filter);
        return doPagination(query, filter, pageIndex, pageSize, total);
    }

    Long countHis(F filter);

    default <M> PagedRecord<M> paginationHis(CriteriaQuery<K, M, F> query, F filter, int pageIndex, int pageSize) {
        Long total = this.countHis(filter);
        return doPagination(query, filter, pageIndex, pageSize, total);
    }

    default <M> PagedRecord<M> doPagination(CriteriaQuery<K, M, F> query, F filter, int pageIndex, int pageSize, Long total) {
        if (total == 0) {
            return PagedRecord.empty(pageIndex, pageSize);
        }
        try {
            PaginationContext.currentContext().beginPagination(pageIndex, pageSize);
            return PagedRecord.of(pageIndex, pageSize, total, query.execute(filter));
        } finally {
            PaginationContext.currentContext().releasePagination();
        }
    }
}
